package com.sxyjhh.dbutil.dao;

import com.mongodb.BasicDBObject;
import com.mongodb.Block;
import com.mongodb.DBCursor;
import com.mongodb.async.SingleResultCallback;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Projections;
import com.mongodb.client.model.Sorts;
import com.sxyjhh.dbutil.entity.QueryRecord;
import com.sxyjhh.dbutil.utils.DBConstConfig;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.bson.BsonDocument;
import org.bson.BsonInt32;
import org.bson.Document;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * Created by wangchun on 2016/3/31.
 */
public class QueryRecordDao {

    private static QueryRecordDao instance;

    private QueryRecordDao() {
    }

    public static QueryRecordDao getInstance() {
        if (instance == null) {
            instance = new QueryRecordDao();
        }
        return instance;
    }

    public void saveQueryRecord(QueryRecord queryRecord) throws SQLException {
        MongoDatabase mongoDatabase = LocalMongodbDataSource.getInstance().getMongoDatabase();
        //每一个任务存储一张表id，这样对查询也可以优化
        MongoCollection<Document> collection = mongoDatabase.getCollection(queryRecord.getTaskId());

        Document doc = new Document(DBConstConfig.QueryRecordColumnName.DB_NAME, queryRecord.getDb_name())
                .append(DBConstConfig.QueryRecordColumnName.TABLE_NAME, queryRecord.getTable_name())
                .append(DBConstConfig.QueryRecordColumnName.TABLE_ID, queryRecord.getTable_id())
                .append(DBConstConfig.QueryRecordColumnName.CREATE_TIME, queryRecord.getCreate_time())
                .append(DBConstConfig.QueryRecordColumnName.UPDATE_TIME, queryRecord.getUpdate_time())
                .append(DBConstConfig.QueryRecordColumnName.STATUS, queryRecord.getStatus());

        collection.insertOne(doc);
    }

    public List<String> getTableIdList(String dbName, String tableName, String taskId) throws SQLException {
        List<String> ids = new ArrayList<>();

        MongoDatabase mongoDatabase = LocalMongodbDataSource.getInstance().getMongoDatabase();
        MongoCollection<Document> collection = mongoDatabase.getCollection(taskId);

        ArrayList<Document> result = collection.find(
                Filters.and(Filters.eq(DBConstConfig.QueryRecordColumnName.DB_NAME, dbName),
                        Filters.eq(DBConstConfig.QueryRecordColumnName.TABLE_NAME, tableName)))
                .projection(Projections.fields(Projections.include(DBConstConfig.QueryRecordColumnName.TABLE_ID),
                        Projections.excludeId())).into(new ArrayList<Document>());

        for (Document document : result) {
            String tableId = document.getString(DBConstConfig.QueryRecordColumnName.TABLE_ID);
            ids.add(tableId);
        }
        return ids;
    }

    public void saveQueryRecordBatch(List<QueryRecord> queryRecordList) throws SQLException {
        MongoDatabase mongoDatabase = LocalMongodbDataSource.getInstance().getMongoDatabase();
        //每一个任务存储一张表id，这样对查询也可以优化
        MongoCollection<Document> collection = null;
        if (queryRecordList != null && queryRecordList.size() > 0) {
            collection = mongoDatabase.getCollection(queryRecordList.get(0).getTaskId());
        }

        List<Document> documents = new ArrayList<>();
        for (QueryRecord queryRecord : queryRecordList) {
            Document doc = new Document(DBConstConfig.QueryRecordColumnName.DB_NAME, queryRecord.getDb_name())
                    .append(DBConstConfig.QueryRecordColumnName.TABLE_NAME, queryRecord.getTable_name())
                    .append(DBConstConfig.QueryRecordColumnName.TABLE_ID, queryRecord.getTable_id())
                    .append(DBConstConfig.QueryRecordColumnName.CREATE_TIME, queryRecord.getCreate_time())
                    .append(DBConstConfig.QueryRecordColumnName.UPDATE_TIME, queryRecord.getUpdate_time())
                    .append(DBConstConfig.QueryRecordColumnName.STATUS, queryRecord.getStatus());
            documents.add(doc);
        }

        collection.insertMany(documents);
    }

    public Date getMaxCreateTime(String dbName, String tableName, String taskId) throws SQLException {
        MongoDatabase mongoDatabase = LocalMongodbDataSource.getInstance().getMongoDatabase();
        MongoCollection<Document> collection = mongoDatabase.getCollection(taskId);

        Document result = collection
                .find(
                        Filters.and(Filters.eq(DBConstConfig.QueryRecordColumnName.DB_NAME, dbName),
                                Filters.ne(DBConstConfig.QueryRecordColumnName.CREATE_TIME, null),
                                Filters.eq(DBConstConfig.QueryRecordColumnName.TABLE_NAME, tableName)))
                .sort(Sorts.descending(DBConstConfig.QueryRecordColumnName.CREATE_TIME))
                .projection(Projections.fields(Projections.include(DBConstConfig.QueryRecordColumnName.CREATE_TIME),
                        Projections.excludeId())).first();

        return result == null ? null : result.getDate(DBConstConfig.QueryRecordColumnName.CREATE_TIME);
    }

    public Date getMaxUpdateTime(String dbName, String tableName, String taskId) throws SQLException {
        MongoDatabase mongoDatabase = LocalMongodbDataSource.getInstance().getMongoDatabase();
        MongoCollection<Document> collection = mongoDatabase.getCollection(taskId);

        Document result = collection
                .find(
                        Filters.and(Filters.eq(DBConstConfig.QueryRecordColumnName.DB_NAME, dbName),
                                Filters.ne(DBConstConfig.QueryRecordColumnName.UPDATE_TIME, null),
                                Filters.eq(DBConstConfig.QueryRecordColumnName.TABLE_NAME, tableName)))
                .sort(Sorts.descending(DBConstConfig.QueryRecordColumnName.UPDATE_TIME))
                .projection(Projections.fields(Projections.include(DBConstConfig.QueryRecordColumnName.UPDATE_TIME),
                        Projections.excludeId())).first();

        return result == null ? null : result.getDate(DBConstConfig.QueryRecordColumnName.UPDATE_TIME);
    }

    public void dropRecordByTaskId(String taskId) {
        MongoDatabase mongoDatabase = LocalMongodbDataSource.getInstance().getMongoDatabase();
        MongoCollection<Document> collection = mongoDatabase.getCollection(taskId);
        collection.drop();
    }

    public static void main(String[] args) {

    }
}
